﻿package com.hirokimo.display
{
	import com.hirokimo.event.ImageLoaderEvent;
	import com.hirokimo.utils.ScaleController;
	import com.hirokimo.utils.ScaleControllerMode;
	import flash.display.Bitmap;
	import flash.display.BitmapData;
	import flash.display.Loader;
	import flash.display.LoaderInfo;
	import flash.display.Sprite;
	import flash.events.Event;
	import flash.events.EventDispatcher;
	import flash.events.HTTPStatusEvent;
	import flash.events.IOErrorEvent;
	import flash.events.ProgressEvent;
	import flash.net.URLRequest;
	
    /**  
    * 当图片载入完毕且渲染完毕时发送事件  
    * @eventType com.hirokimo.event.ImageLoaderEvent.IMAGE_INIT  
    */  
    [Event(name="image_init", type="com.hirokimo.event.ImageLoaderEvent")]	
    /**  
    * 当图片载入失败 
    * @eventType com.hirokimo.event.ImageLoaderEvent.IMAGE_ERROR  
    */  
    [Event(name="image_error", type="com.hirokimo.event.ImageLoaderEvent")]	
    	
	/**
	 * ImageLoader 载入图片并指定图片不可超越的区域大小,可以指定缩放模式,并选择是否用位图平滑.
	 * 外部可以在收到加载完毕事件后通过getImage方法来获得对图片容器的引用,并取得高宽度.
	 * 
	 * @author	hirokimo
	 * 
	 * @example
	 * 
	 * 			<listing version="3.0">
	 *				var imageLoader:ImageLoader = new ImageLoader(160,150,ScaleControllerMode.SHOW_ALL,true);
	 *				imageLoader.load("jason.jpg");
	 *				imageLoader.addEventListener(ImageLoaderEvent.IMAGE_INIT,__onImageInit);
	 * 			
	 * 			private function __onImageInit(evt:ImageLoaderEvent):void
	 *				{
	 *					var imageLoader:ImageLoader = evt.target as ImageLoader;
	 *					imageLoader.removeEventListener(ImageLoaderEvent.IMAGE_INIT,__onImageInit);
	 *					addChild(imageLoader.getImage());					
	 *					trace("加载成功 宽x高 = "+evt.args.width+"x"+evt.args.height);
	 *				}
	 * 			</listing>
	 */
	public class ImageLoader extends EventDispatcher
	{
		private var area_width:int;
		private var area_height:int;
		private var bitmapSmooth:Boolean;
		private var loader:Loader;
		private var dummy:Sprite;
		private var image:Sprite;
		private var scaleMode:String;
		
		/**
		 * 构造函数
		 * 
		 * @param _w 不可超越的区域宽度
		 * @param _h 不可超越的区域高度
		 * @param _scaleMode 采用什么方式缩放图片 默认 exactFit
		 * @param _bitmapSmooth 是否启用位图平滑(会降低渲染速度) 默认 false
		 * @param _image 加载图片的容器Sprite 默认 null
		 */
		public function ImageLoader(_w:int,_h:int,_scaleMode:String = "exactFit",_bitmapSmooth:Boolean = false,_image:Sprite = null)
		{
			scaleMode = _scaleMode;
			area_width = _w;
			area_height = _h;
			bitmapSmooth = _bitmapSmooth;
			loader = new Loader();
			configureListeners(loader.contentLoaderInfo);			
			dummy = new Sprite();
			
			if(_image == null)
			{
				image = new Sprite();
			}
			else
			{
				image = _image;
			}	
		}
		/**
		 * 加载图片数据
		 * 
		 * @param _path 图片路径
		 */	
		public function load(_path:String):void
		{
			loader.load(new  URLRequest(_path));	
		}
		/**
		 * 获取图片对象
		 * 
		 * @return 加载后的图像引用
		 */			
		public function getImage():Sprite
		{
			return image;
		}
		private function configureListeners(dispatcher:LoaderInfo):void 
		{
			dispatcher.addEventListener(Event.COMPLETE, __onLoadComplete);
			dispatcher.addEventListener(HTTPStatusEvent.HTTP_STATUS, __onHttpStatus);
			dispatcher.addEventListener(IOErrorEvent.IO_ERROR, __onIOError);
			dispatcher.addEventListener(ProgressEvent.PROGRESS, __onProgress);
		}
		private function destroyListeners(dispatcher:LoaderInfo):void 
		{
			dispatcher.removeEventListener(Event.COMPLETE, __onLoadComplete);
			dispatcher.removeEventListener(HTTPStatusEvent.HTTP_STATUS, __onHttpStatus);
			dispatcher.removeEventListener(IOErrorEvent.IO_ERROR, __onIOError);
			dispatcher.removeEventListener(ProgressEvent.PROGRESS, __onProgress);
		}      
		private function __onLoadComplete(evt:Event):void 
		{
			var loaderInfo:LoaderInfo = evt.target as LoaderInfo;
			
			destroyListeners(loaderInfo);
         	
			var image_width:int = Math.ceil(loaderInfo.content.width);
			var image_height:int = Math.ceil(loaderInfo.content.height);
			
        	if(bitmapSmooth)
        	{
				var bmd:BitmapData = new BitmapData(image_width, image_height);
				bmd.draw(loaderInfo.content);
				var bm:Bitmap = new Bitmap(bmd,"auto",true);
				dummy.addChild(bm);
	        }
			else
			{
				dummy.addChild(loader);
			}
						
			fillImage();
			
			var w:int = area_width>dummy.width?dummy.width:area_width;
			var h:int = area_width>dummy.height?dummy.height:area_height; 
			var e:ImageLoaderEvent = new ImageLoaderEvent(ImageLoaderEvent.IMAGE_INIT); 
			e.args = {width:w,height:h}; 
			dispatchEvent(e);
		}
		private function fillImage():void
		{			
			switch ( scaleMode )
			{
				case "exactFit" :
					ScaleController.apply(dummy,dummy.width,dummy.height,area_width,area_height,ScaleControllerMode.EXACT_FIT);
					break;
					
				case "noBorderAbsoluteCentre" :
					ScaleController.apply(dummy,dummy.width,dummy.height,area_width,area_height,ScaleControllerMode.NO_BORDER_ABSOLUTE_CENTRE);						
					break;

				case "noBorderTopCentre" :
					ScaleController.apply(dummy,dummy.width,dummy.height,area_width,area_height,ScaleControllerMode.NO_BORDER_TOP_CENTRE);						
					break;
					
				case "showAll" :
					ScaleController.apply(dummy,dummy.width,dummy.height,area_width,area_height,ScaleControllerMode.SHOW_ALL);
					break;					
			}
			
			var mask:Sprite = new Sprite();
			mask.graphics.beginFill(0xFFFFFF);
			mask.graphics.drawRect(0,0,area_width,area_height);
			mask.graphics.endFill();
							
			image.addChild(mask);
			image.addChild(dummy);
			dummy.mask = mask;
		}
		
		private function __onHttpStatus(event:HTTPStatusEvent):void 
		{
			trace("__onHttpStatus: " + event);
		}

		private function __onIOError(event:IOErrorEvent):void 
		{
			trace("__onIOError: " + event.text);
			var e:ImageLoaderEvent = new ImageLoaderEvent(ImageLoaderEvent.IMAGE_ERROR); 
			e.args = {info:"io_error"}; 
			dispatchEvent(e);
		}
        
		private function __onProgress(event:ProgressEvent):void 
 		{
			//trace("__onProgress: 加载 =" + event.bytesLoaded + " 总共 =" + event.bytesTotal);
		}

	}
}